#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QFile>
#include <QDir>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QUrlQuery>
#include "BaiduOCR.h"
#include "BaiduTranslate.h"
#include "global.h"
#include "ConfigData.h"
#include "../platform/common.h"


QString BaiduOCR::OCRTranslate(bool screenshot)
{
    QString result_string = OCRText(screenshot);
    if (result_string == "time out")
        return "time out";
    // word correction
    if (result_string.size() < 20)
    {
        auto front = 0;
        auto back = result_string.size() - 1;
        while (front < result_string.size())
        {
            if (result_string[front].isLetter() == false)
                front++;
            else
                break;
        }
        while (back > 0)
        {
            if (result_string[back].isLetter() == false)
                back--;
            else
                break;
        }
        if (front < back)
            result_string = result_string.mid(front, back - front + 1);
    }
    return BaiduTranslate::instance().TranslateText(result_string);
}

QString BaiduOCR::OCRText(bool screenshot)
{
    if (screenshot)
    {
        imagePath = Platform::monitor().screenShotSync();
        if (imagePath.isEmpty())
            return QString("");
    }
    if (access_token.isEmpty())
        return QString("OCR token is empty");

    QFile pictureFile(imagePath);
    QString imageString;
    if (pictureFile.open(QIODevice::ReadOnly))
    {
        imageString = pictureFile.readAll().toBase64(QByteArray::Base64Encoding).toPercentEncoding();
        pictureFile.close();
    }
    QUrlQuery data;
    data.addQueryItem("image", imageString);
    data.addQueryItem("detect_language", "true");
    // qInfo() << image_string;
    QNetworkRequest req(QUrl("https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic?access_token=" + access_token));
    req.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
    req.setHeader(QNetworkRequest::UserAgentHeader, "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) "
                                                    "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36");
    QNetworkReply *reply = manager->post(req, data.toString().toUtf8());
    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);

    loop.exec();

    QJsonDocument doc = QJsonDocument::fromJson(reply->readAll());
    QJsonObject obj = doc.object();
    if (obj.contains("error"))
    {
        qInfo() << "OCR: " << obj;
        qWarning() << "OCR: baidu sdk error";
    }
    reply->deleteLater();
    QString result_string;
    auto array = obj["words_result"].toArray();
    for (auto item : array)
    {
        result_string += item.toObject()["words"].toString() + " ";
    }
    return result_string;
}

BaiduOCR::BaiduOCR()
{
    manager = networkManagerInstance();
    checkAccessToken();
}

bool BaiduOCR::getAccessTokenFromURL()
{
    QString res = getUrl(ConfigData::instance().translate->baiduTokenURL->get());
    QJsonDocument doc = QJsonDocument::fromJson(res.toUtf8());
    if (doc.object().contains("access_token") == false ||  doc.object().contains("expires_at") == false)
        return false;

    access_token = doc.object()["access_token"].toString();
    QFile file(Platform::dataDir.filePath("token"));
    if (file.open(QIODevice::WriteOnly))
    {
        file.write(res.toUtf8());
        file.close();
    }
    return true;
}

bool BaiduOCR::checkAccessToken()
{
    bool ret = true;
    QFile file(Platform::dataDir.absoluteFilePath("token"));
    if (file.exists() == false)
        ret = getAccessTokenFromURL();
    else
    {
        if (file.open(QIODevice::ReadOnly))
        {
            QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
            if (time(nullptr) > doc.object()["expires_at"].toVariant().toLongLong())
                ret = getAccessTokenFromURL();
            else
                access_token =  doc.object()["access_token"].toString();
        }
    }
    if (!ret)
        qWarning() << "获取 OCR token 失败";
    return ret;
}

QString BaiduOCR::getUrl(QString url_str)
{
    QUrl url(url_str);
    QNetworkRequest req(url);
    req.setHeader(QNetworkRequest::UserAgentHeader, "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) "
                                                    "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36");
    QNetworkReply *reply = manager->get(req);
    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();
    if (reply->error() != QNetworkReply::NoError)
    {
        qWarning() << reply->errorString();
    }
    QString res = QString::fromUtf8(reply->readAll());
    reply->deleteLater();
    return res;
}
